package SystemC;

import EventPackage.Event;
import EventPackage.EventManagerInterface;
import EventPackage.EventQueue;
import InstrumentationPackage.MessageWindow;

public class MaintenanceMonitor extends Thread {
	
	protected int subSystemHaltEnvId;
	protected String EvtMgrIP = "localhost";		// Event Manager IP address
	protected EventManagerInterface em = null;		// Interface object to the event manager
	protected EventQueue eq = null;					// Message Queue
	protected Event Evt = null;						// Event object
	protected boolean Done = false;					// Loop termination flag
	protected int Delay = 2500;						// The loop delay (2.5 seconds)
	protected String name = null;					// Participant's name
	protected boolean registered = true;			// Signifies that this class is registered with an event manager.
	protected MessageWindow mw; 	// Message Window
	protected String mwTitle;
	protected int mwXpos;
	protected int mwYpos;
	protected int mwHeight;
	protected int mwWidth;
	protected String args[];
	private final int listEquipmentEvtId = 21;
	
	public MaintenanceMonitor(String name, int Xpos, int Ypos, int mwHeight, int mwWidthString, String[] args, int subSystemHaltEnvId) {
		super();
		
		this.name = name;
		//this.mwTitle = mwTitle;
		//this.mwXpos = mwXpos;
		//this.mwYpos = mwYpos;
		this.mwHeight = mwHeight;
		//this.mwWidth = mwWidth;
		this.args = args;
		this.subSystemHaltEnvId = subSystemHaltEnvId;
		
		/////////////////////////////////////////////////////////////////////////////////
		// Try to register with the event manager
		/////////////////////////////////////////////////////////////////////////////////

 		em = register(args);
	}
	
	protected EventManagerInterface register(String args[]) {
		EventManagerInterface em = null;	// Interface object to the event manager

		System.out.println("\n\nAttempting to register on the machine:: " + EvtMgrIP );
		System.out.println("\n\nAttempting to register on the machine args:: " + args.length );
		
		try
		{
	 		if ( args.length == 0 )
	 		{
				// event manager is on the local system
				em = new EventManagerInterface(EvtMgrIP);
			} else {

				// event manager is not on the local system
				EvtMgrIP = args[0];

				em = new EventManagerInterface(EvtMgrIP);
 			} // if
		}
		catch (Exception e)
		{
			System.out.println("Error instantiating event manager interface: " + e);
			registered = false;

		} // catch

		return em;
	}

	protected void customHalt() {
		// TODO Auto-generated method stub

	}

	protected void initialPostPhase() {
		// TODO Auto-generated method stub

	}

	protected void handlePhase() {
		// TODO Auto-generated method stub

	}

	protected void finalPostPhase() {
		// TODO Auto-generated method stub

	}

	protected void beforeLooping() {
		// Call for participant alarms
		//postEvent(monitorPingEvtId);
	}
	
	public void listEquipments() {
		mw.WriteMessage("Request active equipment ...");
		postEvent(listEquipmentEvtId, "AS");
	}
	
	protected void postEvent(int EvtId, String EvtMsg)
	{
		// Here we create the event.
		Event evt = new Event(EvtId);

		// Here we send the event to the event manager.
		try
		{
			em.SendEvent(evt);
			//mw.WriteMessage( "Sent Humidity Event" );

		} // try

		catch (Exception e)
		{
			System.out.println( "Error Posting Event:: " + e );

		} // catch

	} // postEvent
	
	public void Halt()
	{
		mw.WriteMessage( "***HALT MESSAGE RECEIVED - SHUTTING DOWN SYSTEM***" );

		// Here we create the stop event.

		Event evt;

		evt = new Event( (int) 91, "XXX" );

		// Here we send the event to the event manager.

		try
		{
			em.SendEvent( evt );

		} // try

		catch (Exception e)
		{
			System.out.println("Error sending halt message:: " + e);

		} // catch

	} // Halt
	
	public void CompleteHalt()
	{
		mw.WriteMessage( "***HALT MESSAGE RECEIVED - SHUTTING DOWN THE ENTIRE SYSTEM***" );

		// Here we create the stop event.

		Event evt;

		evt = new Event( (int) 99, "XXX" );

		// Here we send the event to the event manager.

		try
		{
			em.SendEvent( evt );

		} // try

		catch (Exception e)
		{
			System.out.println("Error sending halt message:: " + e);

		} // catch

	} // Halt

	public boolean isRegistered() {
		return registered;
	}
	
	
	public void run()
	{
		Event Evt = null;				// Event object
		EventQueue eq = null;			// Message Queue
		int EvtId = 0;					// User specified event ID
		int	Delay = 1000;				// The loop delay (1 second)
		boolean Done = false;			// Loop termination flag
		String listOfEquipment = null;  // The list of Inactive Equipments

		if (em != null)
		{
			// Now we create the ECS status and message panel
			// Note that we set up two indicators that are initially yellow. This is
			// because we do not know if the temperature/humidity is high/low.
			// This panel is placed in the upper left hand corner and the status 
			// indicators are placed directly to the right, one on top of the other

			mw = new MessageWindow("Maintenance Console", 0, 0);

			mw.WriteMessage( "Registered with the event manager." );

	    	try
	    	{
				mw.WriteMessage("   Participant id: " + em.GetMyId() );
				mw.WriteMessage("   Registration Time: " + em.GetRegistrationTime() );

			} // try

	    	catch (Exception e)
			{
				System.out.println("Error:: " + e);

			} // catch

			/********************************************************************
			** Here we start the main simulation loop
			*********************************************************************/

			while ( !Done )
			{
				// Here we get our event queue from the event manager

				try
				{
					eq = em.GetEventQueue();

				} // try

				catch( Exception e )
				{
					mw.WriteMessage("Error getting event queue::" + e );

				} // catch

				// If there are messages in the queue, we read through them.
				// We are looking for EventIDs = 26. Event IDs 26, 
				// which contains the list of non-responding equipment.

				int qlen = eq.GetSize();

				for ( int i = 0; i < qlen; i++ )
				{
					Evt = eq.GetEvent();
                                        
                                        if ( Evt.GetEventId() == 25 ) // List of Equipments
					{
						try
						{
							listOfEquipment = Evt.GetMessage();
							displayActiveEquipment(listOfEquipment);

						} // try

						catch( Exception e )
						{
							mw.WriteMessage("Error reading list of active equipments: " + e);

						} // catch

					} // if

					if ( Evt.GetEventId() == 26 ) // Non-responding equipment 
					{
						try
						{
							listOfEquipment = Evt.GetMessage();
							displayInactiveEquipment(listOfEquipment);

						} // try

						catch( Exception e )
						{
							mw.WriteMessage("Error reading temperature: " + e);

						} // catch

					} // if


					// If the event ID == 99 then this is a signal that the simulation
					// is to end. At this point, the loop termination flag is set to
					// true and this process unregisters from the event manager.

					if ( Evt.GetEventId() == 99 )
					{
						Done = true;

						try
						{
							em.UnRegister();

				    	} // try

				    	catch (Exception e)
				    	{
							mw.WriteMessage("Error unregistering: " + e);

				    	} // catch

				    	mw.WriteMessage( "\n\nSimulation Stopped. \n");


					} // if

				} // for

				// This delay slows down the sample rate to Delay milliseconds

				try
				{
					Thread.sleep( Delay );

				} // try

				catch( Exception e )
				{
					System.out.println( "Sleep error:: " + e );

				} // catch

			} // while

		} else {

			System.out.println("Unable to register with the event manager.\n\n" );

		} // if

	} // main
	
	/**
	 * Display the list of active equipments
	 * @param listOfEquipments string containing all inactive equipment
	 */
	private void displayInactiveEquipment(String listOfEquipment) {
		
		mw.WriteMessage("List of inactive equipment:");
	
		// Split the string with equipment, which are divided by a semicolon (;).
		String[] list = listOfEquipment.split(";");
		for (int i = 0; i < list.length; i++) {
			mw.WriteMessage(list[i] + "\n");
		}
	}
        
        /**
	 * Display the list of active equipments
	 * @param listOfEquipments string containing all active equipment
	 */
	private void displayActiveEquipment(String listOfEquipment) {
		
		System.out.println("List of active equipment:");
	
		// Split the string with equipment, which are divided by a semicolon (;).
		String[] list = listOfEquipment.split(";");
		for (int i = 0; i < list.length; i++) {
			System.out.println(list[i]);
		}
	}
}
